package com.woniuxy.yoga.course.service.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.yoga.coach.dao.model.Coach;
import com.woniuxy.yoga.commons.core.model.PageInfo;
import com.woniuxy.yoga.commons.core.model.Result;
import com.woniuxy.yoga.commons.core.statedata.*;
import com.woniuxy.yoga.course.client.*;
import com.woniuxy.yoga.course.client.dto.business.BusinessStoreDTO;
import com.woniuxy.yoga.course.client.dto.order.OrderInfoDto;
import com.woniuxy.yoga.course.client.dto.product.PrivateProductByIdDTO;
import com.woniuxy.yoga.course.client.dto.user.UserInfoDTO;
import com.woniuxy.yoga.course.client.form.CreatePriOrderForm;
import com.woniuxy.yoga.course.dao.model.AloneReservation;
import com.woniuxy.yoga.course.dao.mapper.AloneReservationMapper;
import com.woniuxy.yoga.course.model.dto.alone.AloneReservationDTO;
import com.woniuxy.yoga.course.model.dto.alone.CoachQueryMyAloneReservationDTO;
import com.woniuxy.yoga.course.model.dto.alone.UserQueryMyAloneReservationDTO;
import com.woniuxy.yoga.course.model.exception.CourseException;
import com.woniuxy.yoga.course.model.exception.CourseExceptionCode;
import com.woniuxy.yoga.course.model.param.alone.AddAloneReservationParam;
import com.woniuxy.yoga.course.model.param.alone.CoachQueryMyAloneReservationParam;
import com.woniuxy.yoga.course.model.param.alone.UserQueryMyAloneReservationParam;
import com.woniuxy.yoga.course.service.service.AloneReservationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 私教预约表 服务实现类
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年11月28日
 */
@Service
public class AloneReservationServiceImpl extends ServiceImpl<AloneReservationMapper, AloneReservation> implements AloneReservationService {

    @Autowired
    private AloneReservationMapper aloneReservationMapper;

    @Autowired
    private ProductClient productClient;

    @Autowired
    private CoachClient coachClient;

    @Autowired
    private UserClient userClient;

    @Autowired
    private BusinessClient businessClient;

    @Autowired
    private OrderClient orderClient;

    /**
     * 教练ID查询预约信息
     * @param ids
     * @return
     */
    @Override
    public List<AloneReservationDTO> getReservationByCoachId(List<Integer> ids) {
        QueryWrapper<AloneReservation> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_id",ids.get(0));
        //索引排序
        wrapper.orderByAsc("reservation_id");
        List<AloneReservation> aloneReservations = aloneReservationMapper.selectList(wrapper);
        //数据转换
        List<AloneReservationDTO> aloneReservationDTOS = BeanUtil.copyToList(aloneReservations, AloneReservationDTO.class);
        return aloneReservationDTOS;
    }

    /**
     * 新增私教预约信息
     * @param param
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void addAloneReservation(AddAloneReservationParam param) {
        //判断私教产品是否报错
        Result<PrivateProductByIdDTO> privateProductByIdDTOResult = productClient.getPrivateProductById(param.getPrivateProductId());
        if (privateProductByIdDTOResult.getCode()!=200) throw new CourseException(privateProductByIdDTOResult.getCode(),privateProductByIdDTOResult.getMessage());
        //获取数据
        PrivateProductByIdDTO privateProductByIdDTO = privateProductByIdDTOResult.getData();
        //判断是否存在
        if (privateProductByIdDTO==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_PRIVATE_PRODUCT_NOT_EXIST);
        //判断私教产品状态是否异常
        if (privateProductByIdDTO.getPrivateProductState()!= ProductState.PRIVATE_PRODUCT_STATE_NORMAL) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_PRIVATE_PRODUCT_STATE_ERROR);
        //判断教练是否报错
        Result<Coach> coachResult = coachClient.getCoachById(privateProductByIdDTO.getCoachId());
        if (coachResult.getCode()!=200) throw new CourseException(coachResult.getCode(),coachResult.getMessage());
        //获取数据
        Coach coach = coachResult.getData();
        //判断是否存在
        if (coach==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COACH_NOT_EXIST);
        //判断教练状态是否异常
        if (coach.getCoachState()!= CoachState.COACH_STATE_NORMAL) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COACH_STATE_ERROR);
        //判断用户是否报错
        Result<UserInfoDTO> userInfoDTOResult = userClient.getUserByUserId(param.getUserId());
        if (userInfoDTOResult.getCode()!=200) throw new CourseException(userInfoDTOResult.getCode(),userInfoDTOResult.getMessage());
        //获取数据
        UserInfoDTO userInfoDTO = userInfoDTOResult.getData();
        //判断是否存在
        if (userInfoDTO==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_USER_INFO_NOT_EXIST);
        //判断用户状态是否异常
        if (userInfoDTO.getUserState()!= UserState.USER_ACCOUNT_STATE_NORMAL) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_USER_INFO_STATE_ERROR);
        //判断场馆是否报错
        Result<BusinessStoreDTO> businessStoreDTOResult = businessClient.selByBusinessStoreId(privateProductByIdDTO.getStoreId());
        if (businessStoreDTOResult.getCode()!=200) throw new CourseException(businessStoreDTOResult.getCode(),businessStoreDTOResult.getMessage());
        //获取数据
        BusinessStoreDTO businessStoreDTO = businessStoreDTOResult.getData();
        //判断是否存在
        if (businessStoreDTO==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_BUSINESS_STORE_NOT_EXIST);
        //判断场馆状态是否异常
        if (businessStoreDTO.getStoreState()== BusinessState.STORE_STATE_DELETE) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_BUSINESS_STORE_STATE_ERROR);
        //对象转换
        AloneReservation aloneReservation = BeanUtil.toBean(param, AloneReservation.class);
        //教练ID赋值
        aloneReservation.setCoachId(privateProductByIdDTO.getCoachId());
        //门店ID赋值
        aloneReservation.setStoreId(privateProductByIdDTO.getStoreId());
        //私教产品名称赋值
        aloneReservation.setPrivateProductName(privateProductByIdDTO.getPrivateProductName());
        //私教产品价格赋值
        aloneReservation.setPrivateProductPrice(privateProductByIdDTO.getPrivateProductPrice());
        //赋值教练姓名
        aloneReservation.setCoachName(coach.getCoachName());
        //门店名称赋值
        aloneReservation.setStoreName(businessStoreDTO.getStoreName());
        //用户名赋值
        aloneReservation.setUserName(userInfoDTO.getUserName());
        //用户联系方式赋值
        aloneReservation.setUserPhone(userInfoDTO.getUserPhone());
        //设置状态为待确认
        aloneReservation.setReservationState(CourseState.RESERVATION_STATE_PENDING);
        //新增数据
        aloneReservationMapper.insert(aloneReservation);
    }

    /**
     * 私教预约次数减一
     * @param reservationId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reduceAloneReservationCount(Integer reservationId) {
        AloneReservation aloneReservation = aloneReservationMapper.selectById(reservationId);
        //判断是否存在
        if (aloneReservation==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ALONE_RESERVATION_NOT_EXIST);
        //判断私教预约状态是否异常
        if (aloneReservation.getReservationState()!= CourseState.RESERVATION_STATE_CONFIRMED) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ALONE_RESERVATION_STATE_ERROR);
        //判断私教预约次数是否用完
        if (aloneReservation.getCourseCount()==0) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ALONE_COURSE_COUNT_COMPLETE);
        //判断次数是否只剩下一次
        if (aloneReservation.getCourseCount()==1){
            //次数减一 修改预约状态
            aloneReservation.setCourseCount(aloneReservation.getCourseCount()-1);
            aloneReservation.setReservationState(CourseState.RESERVATION_STATE_COMPLETE);
            aloneReservationMapper.updateById(aloneReservation);
        } else if (aloneReservation.getCourseCount()>1) {
            //次数减一
            aloneReservation.setCourseCount(aloneReservation.getCourseCount()-1);
            aloneReservationMapper.updateById(aloneReservation);
        }
    }

    /**
     * 私教预约确认
     * @param reservationId
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void modifyAloneReservationConfirm(Integer reservationId) {
        AloneReservation aloneReservation = aloneReservationMapper.selectById(reservationId);
        //判断是否存在
        if (aloneReservation==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ALONE_RESERVATION_NOT_EXIST);
        //判断私教预约状态是否是待确认
        if (aloneReservation.getReservationState()!=CourseState.RESERVATION_STATE_PENDING) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ALONE_RESERVATION_STATE_ERROR);
        //修改成已确认
        aloneReservation.setReservationState(CourseState.RESERVATION_STATE_CONFIRMED);
        aloneReservationMapper.updateById(aloneReservation);
        //下单对象生成
        CreatePriOrderForm createPriOrderForm = new CreatePriOrderForm();
        createPriOrderForm.setProductId(aloneReservation.getPrivateProductId());
        createPriOrderForm.setTypes(2);
        createPriOrderForm.setRemarks("下单私教");
        createPriOrderForm.setOrderCount(aloneReservation.getCourseCount());
        createPriOrderForm.setUserId(aloneReservation.getUserId());
        //调用方法
        Result<OrderInfoDto> orderInfoDtoResult = orderClient.createOrder(createPriOrderForm);
        if (orderInfoDtoResult.getCode()!=200) throw new CourseException(orderInfoDtoResult.getCode(),orderInfoDtoResult.getMessage());
    }

    /**
     * 私教预约拒绝
     * @param reservationId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyAloneReservationRefuse(Integer reservationId) {
        AloneReservation aloneReservation = aloneReservationMapper.selectById(reservationId);
        //判断是否存在
        if (aloneReservation==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ALONE_RESERVATION_NOT_EXIST);
        //判断私教预约状态是否是待确认
        if (aloneReservation.getReservationState()!=CourseState.RESERVATION_STATE_PENDING) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ALONE_RESERVATION_STATE_ERROR);
        //修改成已拒绝
        aloneReservation.setReservationState(CourseState.RESERVATION_STATE_REFUSE);
        aloneReservationMapper.updateById(aloneReservation);
    }

    /**
     * 教练查询自己的私教预约信息
     * @param param
     * @return
     */
    @Override
    public PageInfo coachQueryMyAloneReservation(CoachQueryMyAloneReservationParam param) {
        QueryWrapper<AloneReservation> wrapper = new QueryWrapper<>();
        //教练ID
        wrapper.eq("coach_id",param.getCoachId());
        //用户名搜素
        if (ObjectUtil.isNotEmpty(param.getUserName())){
            wrapper.like("user_name",param.getUserName());
        }
        //用户联系方式搜索
        if (ObjectUtil.isNotEmpty(param.getUserPhone())){
            wrapper.like("user_phone",param.getUserPhone());
        }
        //状态搜索
        if (ObjectUtil.isNotEmpty(param.getReservationState())){
            wrapper.eq("reservation_state",param.getReservationState());
        }
        //索引排序
        wrapper.orderByAsc("reservation_id");
        //分页查询
        Page<AloneReservation> page = new Page<>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 10 : param.getPageSize());
        aloneReservationMapper.selectPage(page,wrapper);
        //集合转换
        List<CoachQueryMyAloneReservationDTO> coachQueryMyAloneReservationDTOS = new ArrayList<>();
        for (AloneReservation aloneReservation : page.getRecords()) {
            //对象转换
            CoachQueryMyAloneReservationDTO coachQueryMyAloneReservationDTO = BeanUtil.toBean(aloneReservation, CoachQueryMyAloneReservationDTO.class);
            //状态数据赋值
            coachQueryMyAloneReservationDTO.setReservationStateName(aloneReservation.getReservationState()==0?"待确认":aloneReservation.getReservationState()==1?"已确认":aloneReservation.getReservationState()==2?"已拒绝":"已完成");
            //保存到集合中
            coachQueryMyAloneReservationDTOS.add(coachQueryMyAloneReservationDTO);
        }
        //分页对象转换
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(coachQueryMyAloneReservationDTOS);
        return pageInfo;
    }

    /**
     * 用户查询自己的私教预约信息
     * @param param
     * @return
     */
    @Override
    public PageInfo userQueryMyAloneReservation(UserQueryMyAloneReservationParam param) {
        QueryWrapper<AloneReservation> wrapper = new QueryWrapper<>();
        //用户ID
        wrapper.eq("user_id",param.getUserId());
        //私教产品名称搜索
        if (ObjectUtil.isNotEmpty(param.getPrivateProductName())){
            wrapper.like("private_product_name",param.getPrivateProductName());
        }
        //教练姓名搜索
        if (ObjectUtil.isNotEmpty(param.getCoachName())){
            wrapper.like("coach_name",param.getCoachName());
        }
        //门店名称搜索
        if (ObjectUtil.isNotEmpty(param.getStoreName())){
            wrapper.like("store_name",param.getStoreName());
        }
        //状态搜索
        if (ObjectUtil.isNotEmpty(param.getReservationState())){
            wrapper.eq("reservation_state",param.getReservationState());
        }
        //索引排序
        wrapper.orderByAsc("reservation_id");
        //分页查询
        Page<AloneReservation> page = new Page<>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 10 : param.getPageSize());
        aloneReservationMapper.selectPage(page,wrapper);
        //集合转换
        List<UserQueryMyAloneReservationDTO> userQueryMyAloneReservationDTOS = new ArrayList<>();
        for (AloneReservation aloneReservation : page.getRecords()) {
            //对象转换
            UserQueryMyAloneReservationDTO userQueryMyAloneReservationDTO = BeanUtil.toBean(aloneReservation, UserQueryMyAloneReservationDTO.class);
            //状态赋值
            userQueryMyAloneReservationDTO.setReservationStateName(aloneReservation.getReservationState()==0?"待确认":aloneReservation.getReservationState()==1?"已确认":aloneReservation.getReservationState()==2?"已拒绝":"已完成");
            //保存到集合中
            userQueryMyAloneReservationDTOS.add(userQueryMyAloneReservationDTO);
        }
        //分页对象转换
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(userQueryMyAloneReservationDTOS);
        return pageInfo;
    }
}
